#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <vector>
using namespace std;
void test_vector1()
{
	vector<int> v1;//无参的构造
	vector<int> v2(10, 1);//n个value构造
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	v1.push_back(5);
	//遍历
	for (int i = 0; i < v1.size(); i++)
	{
		cout << v1[i] << " ";
	}
	cout << endl;
	//迭代器 - 遍历
	vector<int>::iterator it1 = v1.begin();
	while (it1 != v1.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;
	//范围for
	for (const auto& index : v1)
	{
		cout << index << " ";
	}
	cout << endl;
}
void test_vector2()
{
	string s1;
	vector<char> vs;
	/*
	这两个是有区别的
	1.string后面默认有'\0',vector<char>后面没有'\0',
	因为这个链表不可能只存char类型的数据,还要存其他类型
	2.它们的接口功能上面也会有很大的区别,string有串的概念
	有时间插入一个字符,但有时候插入一个字符串,但vector没有
	虽然有很强的相似性,但是还是有很大的差别。
	那么就可以用string去实例化一个vector
	*/
	//这样写就可以push_back一个string对象
	vector<string> vstr;
	string s = "张三";
	vstr.push_back(s);
	//走隐式类型转换
	vstr.push_back("李四");
	//范围for - 遍历
	//范围for是替换成迭代器,替换成迭代器了是把*it1
	//赋值给e,*it1是一个string,string赋值给e就会调用
	//拷贝构造,以前是int的话拷贝给e无所谓,但这里是string类
	//调string的拷贝构造就要开空间,代价有点大,所以这里可以
	//用引用,如果不修改,再把const加上
	for (const auto& e : vstr)
	{
		cout << e << " ";
	}
	cout << endl;
	/**********************************************************/
	//修改
	vstr[0] += 'h';
	//支持+=是因为第0个元素是string,string支持+=接口
	//可以+=一个字符,也可以++一个字符串
	vstr[1] += "haha";

	vstr[0][0]++;
	vstr[0][1]++;
	//vstr[0]是"张三",汉字是由两个字符组成,所以vstr[0][0]和
	//vstr[0][1]组成"张",对这两个++就改变了"张",如果只对
	//vstr[0][1]++就变成了"张"的同音字
	//所以就等价于:vstr.operator[](0).operator[](1) ++ ;
	//vstr[0][0]++;在底层也是调用vstr.operator[](0).operator[](1) ++ ;
	/*****************************************************/
	//遍历
	for (const auto& e : vstr)
	{
		cout << e << " ";
	}
	cout << endl;
}
void test_vector3()
{
	vector<int> v;
	for (int i = 1; i <= 10; i++)
	{
		v.push_back(i);
	}
	//[ ]+下标遍历
	for (int i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;
	//迭代器遍历
	auto it1 = v.begin();
	while (it1 != v.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;
	//[ ]+下标修改
	for (int i = 0; i < v.size(); i++)
	{
		v[i] = 11 + i;
	}
	//[ ]+下标遍历
	for (int i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;
	//迭代器修改
	it1 = v.begin();
	int x = v[v.size()-1];
	while (it1 != v.end())
	{
		*it1 = ++x;
		it1++;
	}
	//迭代器遍历
	it1 = v.begin();
	while (it1 != v.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;
}
void test_vector4()
{
	//可以像初始化数组一样的初始化操作
	//这个初始化走的是C++11中的一个构造
	//这里本质算是类型转换
	/*
	单参数构造函数支持隐式类型转换,
	*/
	vector<int> v1 = { 1,2,3,4,5,6,7,8,9 };
	vector<int> v2({ 1,2,3,4,5,6,7,8,9 });
	//上面的两种写法结果都是调用构造,但是语法
	//逻辑上是不一样的
	/*
	vector<int> v = { 1,2,3,4,5,6,7,8,9 };
	这个其实是一个隐式类型转换,参数是initializer_list
	的对象,是不能传给v这个对象的,语法逻辑上是要用
	initializer_list去构造一个临时对象,然后再去拷贝构造
	但是连续的构造+拷贝构造编译器优化了,优化成了直接构造
	vector<int> v({ 1,2,3,4,5,6,7,8,9 });
	这个就直接构造了,因为就直接传给了initializer_list
	auto il1 = { 1,2,3,4,5,6,7,8,9 };
	initializer_list<int> il2 = { 1,2,3,4,5,6,7,8,9 };
	这个类型就是initializer_list，也可以显示的写
	底层原理:比如说给了三个值进行初始化, 它在底层会去开
	一个数组,然后把这些值拷贝到数组中,然后这个对象中有两
	个指针,指向这段数组空间,指向这个数组的开始和结束位置
	其实有点像C语言中的数组
	int arr[] = { 1,2,3,4,5,6,7,8,9 };
	vector<int> v = { 1,2,3,4,5,6,7,8,9 };
	所以说支持这个的语法是有这样的构造去支持的
	*/
}
void test_vector5()
{
	vector<int> v({ 1,2,3,4,5,6,7,8,9,10 });
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
void test_vector7()
{
	vector<int> v({ 1,2,3,4,5,6});
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	v.insert(v.begin(), 1);
	v.insert(v.begin()+4, 101);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
// 测试vector的默认扩容机制
void TestVectorExpand()
{
	size_t sz;
	vector<int> v;
	sz = v.capacity();
	cout << "making v grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		v.push_back(i);
		if (sz != v.capacity())
		{
			sz = v.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}
//template<class T>
//class vector
//{
//public:
//	T& operator[](size_t i)
//	{
//		assert(i < _size);
//		return _a[i];
//	}
//private:
//	T*	   _a;
//	size_t _size;
//	size_t _capacity;
//};
#include "vector.h"
void test_vector9()
{
	wang::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(5);
	for (int i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	v.pop_back();
	v.pop_back();
	v.pop_back();
	v.pop_back();
	wang::vector<int>::iterator it1 = v.begin();
	while (it1 != v.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;
}
void test_vector10()
{
	wang::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	for (int i = 0; i < v.size(); i++)
	{
		cout << v[i] << " ";
	}
	cout << endl;
	v.erase(v.end()-1);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;

	//initializer_list
	wang::vector<int> v1 = { 1,2,3,4,5,6,7,8,9,10 };
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}
void test_vector11()
{
	cout << typeid(vector<int>::iterator).name() << endl;
}
void test_vector12()
{
	wang::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	//v.insert(v.begin() + 2, 30);
	//迭代器遍历
	wang::vector<int>::iterator it1 = v.begin();
	while (it1 != v.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;
	int x = 0;
	cin >> x;
	wang::vector<int>::iterator it = find(v.begin(), v.end(), x);
	if (it != v.end())
	{
		//用insert的返回值更新it
		it = v.insert(it, 10*x);
		cout << *it << endl;
	}
	//范围for遍历
	for (int e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
void test_vector13()
{
	std::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	//迭代器遍历
	std::vector<int>::iterator it1 = v.begin();
	while (it1 != v.end())
	{
		cout << *it1 << " ";
		it1++;
	}
	cout << endl;
	int x = 0;
	cin >> x;
	std::vector<int>::iterator it = find(v.begin(), v.end(), x);
	if (it != v.end())
	{
		//it是否失效?
		v.erase(it);
		cout << *it << endl;
	}
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
void test_vector14()
{
	wang::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(2);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	v.push_back(2);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	//删除所有的偶数
	auto it = v.begin();
	while (it != v.end())
	{
		if (*it % 2 == 0)
		{
			it = v.erase(it);
		}
		else
		{
			++it;
		}
	}
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
void test_vector15()
{
	int a = int();
	int b = int(1);
	int c(2);
	cout << a << " " << b << " " << c << " " << endl;
}
void test_vector16()
{
	wang::vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	v.push_back(4);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	v.resize(10);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	v.resize(15, 1);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
	v.resize(2);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
//深浅拷贝
void test_vector17()
{
	wang::vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
	wang::vector<int> v2(v1);
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;
	wang::vector<int> v3 = { 10,20,30,40,50 };
	v1 = v3;
	for (auto e : v1)
	{
		cout << e << " ";
	}
	cout << endl;
}
//迭代器区间的构造
void test_vector18()
{
	wang::vector<int> v1;
	v1.push_back(1);
	v1.push_back(2);
	v1.push_back(3);
	v1.push_back(4);
	//可以是vector的迭代器区间
	wang::vector<int> v2(v1.begin(), v1.end());
	for (auto e : v2)
	{
		cout << e << " ";
	}
	cout << endl;
	//也可以是其他容器的迭代器区间,只要能转换成int就可以
	string s("hello");
	wang::vector<int> v3(s.begin(), s.end());
	for (auto e : v3)
	{
		cout << e << " ";
	}
	cout << endl;
}
//n个value的构造
void test_vector19()
{
	wang::vector<int> v(10, 1);
	//wang::vector<double> v(10, 1.1);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
void test_vector20()
{
	wang::vector<string> v;
	v.push_back("1111111111111111111111");
	v.push_back("1111111111111111111111");
	v.push_back("1111111111111111111111");
	v.push_back("1111111111111111111111");
	v.push_back("1111111111111111111111");
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
int main()
{
	test_vector20();
	return 0;
}
